package com.company.nuwa.common.utils;

import cn.hutool.core.util.ReflectUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

/**
 * <p>json工具类</p >
 *
 * @author Lionel Lee
 * @version 1.0: JsonUtils.java
 * @date 2019/12/20 17:18
 */
public class JsonUtils {

    /**
     * 定义jackson对象
     */
    private static ObjectMapper MAPPER = new ObjectMapper()
            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
            .registerModule(new JavaTimeModule());

    /**
     * 可通过该方法，集成到spring项目种注入的ObjectMapper
     *
     * @param mapper
     */
    public static void setMapper(ObjectMapper mapper) {
        JsonUtils.MAPPER = mapper;
    }

    /**
     * 将对象转换成json字符串
     *
     * @param data 对象
     * @return String
     */
    @SneakyThrows
    public static String objectToJson(Object data) {
        return MAPPER.writeValueAsString(data);
    }

    /**
     * 将json结果集转化为对象
     *
     * @param jsonData json数据
     * @param beanType bean类型
     * @param <T>      类型
     * @return T
     */
    @SneakyThrows
    public static <T> T jsonToObject(String jsonData, Class<T> beanType) {
        return StringUtils.isNotBlank(jsonData) ? MAPPER.readValue(jsonData, beanType) : null;
    }


    /**
     * 将json结果集转化为对象，若对象为空字符串，则new instance
     *
     * @param jsonData json数据
     * @param beanType bean类型
     * @param <T>      类型
     * @return T
     */
    @SneakyThrows
    public static <T> T jsonToObjectIfNullNewInstance(String jsonData, Class<T> beanType) {
        return StringUtils.isNotBlank(jsonData) ? MAPPER.readValue(jsonData, beanType) : ReflectUtil.newInstanceIfPossible(beanType);
    }

    /**
     * 将json结果集转化为对象
     *
     * @param jsonData      json数据
     * @param typeReference typeReference
     * @param <T>
     * @return
     */
    @SneakyThrows
    public static <T> T jsonToObject(String jsonData, TypeReference<T> typeReference) {
        return StringUtils.isNotBlank(jsonData) ? MAPPER.readValue(jsonData, typeReference) : null;
    }

    /**
     * 将json数据转换成pojo对象list
     *
     * @param jsonData      json数据
     * @param typeReference 类型
     * @param <T>           类型
     * @return T
     */
    @SneakyThrows
    public static <T> T jsonToList(String jsonData, TypeReference<T> typeReference) {
        return StringUtils.isNotBlank(jsonData) ? MAPPER.readValue(jsonData, typeReference) : null;
    }

    /**
     * 将json数据转换成pojo对象list
     *
     * @param jsonData json数据
     * @param beanType 类型
     * @param <T>      类型
     * @return T
     */
    @SneakyThrows
    public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
        return StringUtils.isNotBlank(jsonData)
                ? MAPPER.readValue(jsonData, new TypeReference<List<T>>() {
        })
                : null;
    }
}